package com.eudon.user.exception;

import com.eudon.user.domain.resp.BaseResp;
import com.eudon.user.enums.RespCode;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author eudon
 * @description 全局异常处理控制器
 * @date 2025/9/8
 * @email syd19970616@gmail.com
 * @address <a href="https://gitee.com/eudon">Gitee</a>
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理 @Valid 校验失败异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public BaseResp handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数校验失败: {}", e.getMessage());

        String errorMessage = e.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(error -> error.getField() + ": " + error.getDefaultMessage())
                .collect(Collectors.joining(", "));

        return BaseResp.ofFail(RespCode.PARAMS_ERROR.getCode(), errorMessage);
    }

    /**
     * 处理 @Validated 校验失败异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public BaseResp handleConstraintViolationException(ConstraintViolationException e) {
        log.error("约束校验失败: {}", e.getMessage());

        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        String errorMessage = violations.stream()
                .map(violation -> violation.getPropertyPath() + ": " + violation.getMessage())
                .collect(Collectors.joining(", "));

        return BaseResp.ofFail(RespCode.PARAMS_ERROR.getCode(), errorMessage);
    }

    @ExceptionHandler(BusinessException.class)
    public BaseResp handle(BusinessException e) {
        log.error(e.getMessage(), e);
        return BaseResp.ofFail(e.getCode(),e.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    public BaseResp handle(RuntimeException e) {
        log.error(e.getMessage(), e);
        return BaseResp.ofFail(RespCode.SYSTEM_ERR0R.getCode(),RespCode.SYSTEM_ERR0R.getDesc());
    }

    @ExceptionHandler(Exception.class)
    public BaseResp handle(Exception e) {
        log.error(e.getMessage(), e);
        return BaseResp.ofFail(RespCode.SYSTEM_ERR0R.getCode(),RespCode.SYSTEM_ERR0R.getDesc());

    }

    @ExceptionHandler(Error.class)
    public BaseResp handle(Error error) {
        log.error(error.getMessage(), error);
        return BaseResp.ofFail(RespCode.SYSTEM_ERR0R.getCode(),RespCode.SYSTEM_ERR0R.getDesc());

    }
}
